/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package boundaries;

import controllers.CalendarManager;
import controllers.PlaceManager;
import entities.City;
import entities.Event;
import entities.Nation;
import entities.OutdoorEvent;
import entities.Place;
import utils.Weather;
import entities.WeatherForecast;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.validation.constraints.Future;
import javax.validation.constraints.NotNull;

/**
 *
 * @author Alberto, Alessandra
 */
@ManagedBean
@ViewScoped
public class EventBean {
    
    @EJB
    private CalendarManager cm;
    
    @EJB
    private PlaceManager pm;
    
    @NotNull(message = "May not be empty")
    private String name;
    
    private Boolean visibility;
    
    @NotNull(message = "Select start time")
    private Date starttime;
    
    @NotNull(message = "Select end time")
    private Date endtime;
    
    @NotNull(message = "Select a date")
    @Future
    private Date date;
    
    private String description;
    
    @NotNull(message = "May not be empty")
    private String address;
    
    @NotNull(message = "Select a country")
    private String country; 
    
    @NotNull(message = "Select a city")
    private String city;  
    
    private Map<String,Map<String,String>> data = new HashMap<String, Map<String,String>>();
    private Map<String,String> countries;
    private Map<String,String> cities;
    
    private String[] selectedweathers;
    private Boolean renderbadpanel = false;
    
    @NotNull(message = "Select a type")
    private String type;
    
    public EventBean () {
        
    }

    public String[] getSelectedweathers() {
        return selectedweathers;
    }

    public void setSelectedweathers(String[] selectedweathers) {
        this.selectedweathers = selectedweathers;
    }
    
    public Date getStarttime() {
        return starttime;
    }

    public void setStarttime(Date starttime) {
        this.starttime = starttime;
    }

    public Date getEndtime() {
        return endtime;
    }

    public void setEndtime(Date endtime) {
        this.endtime = endtime;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Boolean getVisibility() {
        return visibility;
    }

    public void setVisibility(Boolean visibility) {
        this.visibility = visibility;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
    
    public Map<String, Map<String, String>> getData() {
        return data;
    }
 
    public String getCountry() {
        return country;
    }
 
    public void setCountry(String country) {
        this.country = country;
    }
 
    public String getCity() {
        return city;
    }
 
    public void setCity(String city) {
        this.city = city;
    }
 
    public Map<String, String> getCountries() {
        return countries;
    }
 
    public Map<String, String> getCities() {
        return cities;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Boolean getRenderbadpanel() {
        return renderbadpanel;
    }

    public void setRenderbadpanel(Boolean renderbadpanel) {
        this.renderbadpanel = renderbadpanel;
    }
    
    @PostConstruct
    public void init() {
        countries  = new HashMap<String, String>();
        
        Map<String,String> map = null;
        ArrayList<Nation> lnations = new ArrayList<>();
        ArrayList<City> lcities = new ArrayList<>();
        
        lnations.addAll(pm.getAllNations());
        
        Iterator<Nation> iternation = lnations.iterator();
        Nation n = null;
        while (iternation.hasNext()) {
            n = iternation.next();
            countries.put(n.getName(), n.getName());
            map = new HashMap<String, String>();
            lcities = new ArrayList<>();
            lcities.addAll(pm.getCitiesByNation(n));
            Iterator<City> itercity = lcities.iterator();
            City c = null;
            while (itercity.hasNext()) {
                c = itercity.next();
                map.put(c.getName(), c.getName());
            }
            data.put(n.getName(), map);
        }
    }
    
    public void onCountryChange() {
        if(country !=null && !country.equals(""))
            cities = data.get(country);
        else
            cities = new HashMap<String, String>();
    }
    
    public void onTypeChange () {
        if (type.equals("Outdoor")) {
            renderbadpanel = true;
        }  
        else {
            renderbadpanel = false;
        }
            
    }
    
    public String create () {
        Event event = null;
        if (type.equals("Outdoor")) {
            ArrayList<Weather> badweather = new ArrayList<Weather>();
            for (int i=0; i<selectedweathers.length; i++) {
                badweather.add(Weather.valueOf(selectedweathers[i]));
            }
            event = cm.createOutdoorEvent(badweather, name, visibility, starttime.getHours(), starttime.getMinutes(), endtime.getHours(), 
                    endtime.getMinutes(), date, description, pm.createPlace(address, pm.getCity(city, pm.getNation(country))));
        } else if (type.equals("Indoor")) {
            event = cm.createIndoorEvent(name, visibility, starttime.getHours(), starttime.getMinutes(), endtime.getHours(), 
                     endtime.getMinutes(), date, description, pm.createPlace(address, pm.getCity(city, pm.getNation(country))));
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("event", event);
        return "invitepeople?faces-redirect=true";
    }
    
    
    public void validateEndTime (FacesContext context, UIComponent toValidate, Object value) {
        Date endtime = (Date) value;
        Date starttime = (Date) ((UIInput) context.getViewRoot().findComponent("formid:startime")).getValue();
        if (starttime!=null && endtime!=null) {
            if (endtime.getHours() < starttime.getHours()) {
                ((UIInput) toValidate).setValid(false);
                FacesMessage message = new FacesMessage("Time inconsistent");
                context.addMessage(toValidate.getClientId(context), message);
            } else if (endtime.getHours() == starttime.getHours() && endtime.getMinutes() < starttime.getMinutes()) {
                 ((UIInput) toValidate).setValid(false);
                FacesMessage message = new FacesMessage("Time inconsistent");
                context.addMessage(toValidate.getClientId(context), message);
            }
        }
    }
    
}
